#include <errno.h>
#include <unistd.h>
#include "sqlite.h"
#include "channel.h"
#include "redis.h"
#include "mqtt.h"
#include "z_logger.h"

static int mosquitto_check_rc(int rc, const char *method) {
    if (MOSQ_ERR_ERRNO == rc || MOSQ_ERR_KEEPALIVE == rc) {
        log_error("%s = %d, %s", method, errno, strerror(errno));
    } else if (MOSQ_ERR_SUCCESS != rc) {
        log_error("%s = %d, %s", method, rc, mosquitto_strerror(rc));
    }
    return rc;
}

int main(int argc, char *argv[]) {
    int rc, i;

    log_init();

    seqiot_t *seqiot = seqiot_new();
    read_config(seqiot, NULL, 0, 0);

    struct timeval _tv;
    gettimeofday(&_tv, NULL);
    //必须调用一次__timezone才有值
    localtime(&_tv.tv_sec);

    for (i = 0; i < vector_size(&seqiot->catalogs); ++i) {
        data_catalog_t *catalog = vector_get(&seqiot->catalogs, i);
        if (catalog->pub.period < 0) {
            catalog->_next_sched = _tv.tv_sec;
        } else {
            catalog->_next_sched = next_sched(_tv.tv_sec, &catalog->pub);
        }
    }

    mqtt_handler_t mqtt_handler;
    mqtt_handler.ps = mqtt_handler.payload;
    mqtt_handler.pe = mqtt_handler.ps + sizeof(mqtt_handler.payload);
    mqtt_handler.on_device = publish_scada;

    mosquitto_lib_init();
    mqtt_handler.mosq = mosquitto_new("mqtt_pub", false, NULL);
    rc = mosquitto_connect(mqtt_handler.mosq, seqiot->local_address, 1883, 60);
    mosquitto_check_rc(rc, "mosquitto_connect");

    if (!redis_open(seqiot->local_address)) {
        return EXIT_FAILURE;
    }
    while (running) {
        rc = mosquitto_loop(mqtt_handler.mosq, -1, 10);
        mosquitto_check_rc(rc, "mosquitto_loop");
        if (MOSQ_ERR_NO_CONN == rc || MOSQ_ERR_CONN_LOST == rc) {
            rc = mosquitto_reconnect(mqtt_handler.mosq);
            mosquitto_check_rc(rc, "mosquitto_reconnect");
        }

        sched_mqtt_catalog(&mqtt_handler, seqiot);

        usleep(1000 * 1000L);
    }
    redis_close();

    mosquitto_disconnect(mqtt_handler.mosq);
    mosquitto_destroy(mqtt_handler.mosq);
    mosquitto_lib_cleanup();

    seqiot_free(seqiot);
    log_fini();

    return EXIT_SUCCESS;
}